﻿using IOP.Extension.DependencyInjection;
using IOP.SgrA;
using IOP.SgrA.ECS;
using IOP.SgrA.Input;
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Text;

namespace VkSample912
{
    public class TransformSystem : ComponentSystem
    {
        [Autowired]
        private IGraphicsManager GraphicsManager { get; set; }

        private Camera Camera;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="contextManager"></param>
        public TransformSystem()
        {
        }

        public override void Initialization()
        {
            GraphicsManager.TryGetCamera("main", out Camera);
            GraphicsManager.TryGetRenderGroup("Outline", out IRenderGroup renderGourp);
            Archetype outline = ContextManager.CreateArchetype(new OutlineComponent(), new TransformComponent());
            ContextManager.Foreach<TransformGroup>((group) =>
            {
                Context context = ContextManager.GetContext(group.Entity);
                IRenderObject render = context.GetContextRenderObject();
                ContextManager.CreateContexts(context, 1, outline, renderGourp, render);
            });
            base.Initialization();
        }

        public override void Update(TimeSpan timeSpan)
        {
            if (Input.GetMouseButtonState(MouseButton.ButtonLeft).Action == InputAction.Press)
            {
                Vector2 p = Input.GetMousePositionDelta();
                Camera.EncircleFromMouse(Vector3.Zero, p.X, 0, 5f * MathF.PI / 180.0f);
                EventBus.Publish("CameraChanged", Camera, EventTrigger.SystemFrameAfter);
            }
            ContextManager.Foreach<TransformGroup>((group) =>
            {
                Context context = ContextManager.GetContext(group.Entity);
                Matrix4x4 model = Matrix4x4.CreateScale(group.Transform.Scale) *
                Matrix4x4.CreateFromQuaternion(group.Transform.Angle) *
                Matrix4x4.CreateTranslation(group.Transform.Position);
                ref MVPMatrix mvp = ref context.GetMVPMatrix();
                mvp.ModelMatrix = model;
                context.PushToRenderGroup();
                foreach(var child in context.GetChildrens())
                {
                    ref MVPMatrix cMVP = ref child.GetMVPMatrix();
                    cMVP.ModelMatrix = model;
                    child.PushToRenderGroup();
                }
            });
        }
    }
}
